package es.tikitaka.actions.usuarios;

import java.util.List;

import org.hibernate.validator.Email;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.End;
import org.jboss.seam.annotations.FlushModeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.faces.FacesMessages;

import es.tikitaka.dao.MunicipioDicService;
import es.tikitaka.dao.PerfilDicService;
import es.tikitaka.dao.ProvinciaDicService;
import es.tikitaka.dao.UsuarioService;
import es.tikitaka.dictionary.MunicipioDic;
import es.tikitaka.dictionary.PerfilDic;
import es.tikitaka.dictionary.ProvinciaDic;
import es.tikitaka.domain.usuarios.Usuario;

/**
 * 
 * @author Saúl Domínguez
 * @since 2010
 * @category PFC
 */

@Name("userAdmin")
@Scope(ScopeType.CONVERSATION)
public class UserAdminAction {

	private int modo;
	private boolean nuevo;

	private Usuario user;

	private Usuario newUser;
	private String password;
	private String confPassword;
	private String email;
	private String confEmail;
	private String contraseña;
	private boolean guardado = false;

	private List<ProvinciaDic> listaProvincias;
	private List<MunicipioDic> listaMunicipios;
	private List<PerfilDic> listaPerfiles;

	@In(create = true)
	private ProvinciaDicService provinciaService;

	@In(create = true)
	private MunicipioDicService municipioService;

	@In(create = true)
	private UsuarioService usuarioService;

	@In(create = true)
	private PerfilDicService perfilService;

	@In(create = true)
	private UsuarioSearch usuarioSearch;

	/**
	 * Constructor por defecto
	 */
	public UserAdminAction() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * Método para comenzar con el registro de un nuevo usuario
	 */
	public void registrarse() {
		newUser = new Usuario();
		listaProvincias = provinciaService.getList();
		listaPerfiles = perfilService.getList();
		nuevo = true;
		guardado = false;
	}

	/**
	 * 
	 * @param usuario
	 *            Usuario seleccionado de la tabla de resultado
	 * @param modo
	 *            Modo de selección, ya sea en edición o en consulta
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void selectUsuario(Usuario usuario, int md) {
		user = usuario;
		modo = md;
		listaProvincias = provinciaService.getList();
		listaPerfiles = perfilService.getList();
		nuevo = false;
	}

	/**
	 * Método para guardar el registro de un nuevo usuario
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void guardar() {

		guardado = false;

		if (comprobarPassword()) {
			if (comprobarEmail()) {
				if (!comprobarUsername()) {
					if (comprobarPerfil()) {
						if (nuevo) {
							guardado = usuarioService.save(newUser);
						} else {
							guardado = usuarioService.save(user);
						}
						if (guardado) {
							FacesMessages.instance().add(
									"Se ha registrado con éxito.");
						} else {
							FacesMessages
									.instance()
									.add(
											"Se ha producido un error y no se ha podido completar el proceso de registro.");
						}
					}
				}
			}
		}

		if (guardado) {
			limpiar();
		}
	}

	/**
	 * Método que comrpueba el nombre de usuario ya sea para usuarios de nuevo
	 * registro como para usuarios ya registrados
	 * 
	 * @return estado de la comprobación
	 */
	public boolean comprobarUsername() {

		boolean estado = false;

		if (nuevo) {
			if (newUser.getUsername() != null
					&& newUser.getUsername().length() > 0) {
				estado = comprobarUsername(newUser.getUsername());
				if (estado) {
					FacesMessages
							.instance()
							.add(
									"El nombre de usuario (username) no está disponible. Inserte otro distinto");
				}
			} else {
				FacesMessages.instance().add(
						"Debes introducir un nombre de usuario.");
				estado = false;
			}
		} else {
			if (user.getUsername() != null && user.getUsername().length() > 0) {
				estado = comprobarUsername(user.getUsername());
			} else {
				FacesMessages.instance().add(
						"Debes introducir un nombre de usuario.");
				estado = false;
			}
		}
		return estado;
	}

	/**
	 * Método que comprueba si ya existe el nombre de usuario introducido
	 * 
	 * @param username
	 * @return estado de la comprobación (true si no existe, false en caso
	 *         contrario)
	 */
	public boolean comprobarUsername(String username) {
		return usuarioService.existeUsername(username);
	}

	/**
	 * Método que comprueba las contraseñas ya sea para usuarios de nuevo
	 * registro como para usuarios ya registrados
	 * 
	 * @return estado de la comprobacion
	 */
	public boolean comprobarPassword() {

		boolean estado = false;

		if (password != null && confPassword != null && password.length() > 0
				&& confPassword.length() > 0) {
			estado = comprobarPassword(password, confPassword);
			if (!estado) {
				FacesMessages
						.instance()
						.add(
								"La contraseña introducida y su confirmación no coinciden.");
			} else {
				if (nuevo) {
					newUser.setPassword(password);
				} else {
					user.setPassword(password);
				}
			}
		} else {
			if (nuevo) {
				FacesMessages
						.instance()
						.add(
								"Debes introducir una contraseña y confirmarla para poder continuar con el proceso de registro.");
				estado = false;
			} else {
				estado = true;
			}
		}
		return estado;
	}

	/**
	 * Método que comprueba que las dos contraseñas con iguales
	 * 
	 * @param pass
	 * @param conf
	 * @return estado de la comprobación (true si son iguales, false si no)
	 */
	public boolean comprobarPassword(String pass, String conf) {
		if (pass.equals(conf)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Método que comprueba el email ya sea para usuarios de nuevo registro como
	 * para usuarios ya registrados
	 * 
	 * @return estado de la comprobación
	 */
	public boolean comprobarEmail() {

		boolean estado = false;

		if (email != null && confEmail != null && email.length() > 0
				&& confEmail.length() > 0) {
			estado = comprobarEmail(email, confEmail);
			if (!estado) {
				FacesMessages.instance().add(
						"El email introducido y su confirmación no coinciden");
			} else {
				if (nuevo) {
					newUser.setEmail(email);
				} else {
					user.setEmail(email);
				}
			}
		} else {
			if (nuevo) {
				FacesMessages
						.instance()
						.add(
								"Debes introducir un email válido y confirmarlo para poder continuar con el proceso de registro.");
				estado = false;
			} else {
				estado = true;
			}
		}
		return estado;
	}

	/**
	 * Método que comprueba que los dos email introducidos son iguales
	 * 
	 * @param email
	 * @param conf
	 * @return estado de la comprobación (true si son iguales, false si no)
	 */
	public boolean comprobarEmail(String email, String conf) {
		if (email.equals(conf)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Método que comprueba el perfil del usuario tanto si se trata de un nuevo
	 * registro o como si es un usuario ya registrado
	 * 
	 * @return estado de la comprobación
	 */
	public boolean comprobarPerfil() {

		boolean estado = false;

		if (nuevo) {
			if (newUser.getPerfil() == null) {
				PerfilDic perfil;
				perfil = perfilService.obtenerPerfil("Usuario registrado");
				newUser.setPerfil(perfil);
				estado = true;
			} else {
				estado = true;
			}
		} else {
			if (user.getPerfil() == null) {
				FacesMessages
						.instance()
						.add(
								"Debes seleccionar un perfil para poder continuar con el proceso de registro.");
				estado = false;
			} else {
				estado = true;
			}
		}
		return estado;
	}

	/**
	 * Método para cancelar en registro de un nuevo usuario
	 */
	public void cancelar() {
		newUser = null;
		password = null;
		confPassword = null;
		email = null;
		confEmail = null;
	}

	/**
	 * Método para limpiar los datos introducidos en el formulario de
	 * usuario/nuevo usuario
	 */
	public void limpiar() {
		password = null;
		confPassword = null;
		email = null;
		confEmail = null;
		newUser = null;
	}

	/**
	 * Método para inicializar los parámetros al volver al menú de búsqueda de
	 * usuarios
	 */
	public void volver() {
		usuarioService.merge(user);
		limpiar();
	}

	/**
	 * Método para inicializar los parámetros al volver al menú principal de la
	 * aplicación
	 */
	@End
	public void menu() {
		limpiar();
		usuarioSearch.limpiar();
	}

	/*
	 * getters and setters
	 */

	/**
	 * @return
	 */
	public int getModo() {
		return modo;
	}

	/**
	 * 
	 * @param modo
	 */
	public void setModo(int modo) {
		this.modo = modo;
	}

	/**
	 * 
	 * @return
	 */
	public boolean isNuevo() {
		return nuevo;
	}

	/**
	 * 
	 * @param nuevo
	 */
	public void setNuevo(boolean nuevo) {
		this.nuevo = nuevo;
	}

	/**
	 * 
	 * @return
	 */
	public Usuario getUser() {
		return user;
	}

	/**
	 * 
	 * @param user
	 */
	public void setUser(Usuario user) {
		this.user = user;
	}

	/**
	 * 
	 * @return
	 */
	public Usuario getNewUser() {
		return newUser;
	}

	/**
	 * 
	 * @param newUser
	 */
	public void setNewUser(Usuario newUser) {
		this.newUser = newUser;
	}

	/**
	 * 
	 * @return
	 */
	public String getPassword() {
		return password;
	}

	/**
	 * 
	 * @param password
	 */
	public void setPassword(String password) {
		this.password = password;
	}

	/**
	 * 
	 * @return
	 */
	public String getConfPassword() {
		return confPassword;
	}

	/**
	 * 
	 * @param confPassword
	 */
	public void setConfPassword(String confPassword) {
		this.confPassword = confPassword;
	}

	/**
	 * 
	 * @return
	 */
	@Email(message = "No es una dirección de email válida")
	public String getEmail() {
		return email;
	}

	/**
	 * 
	 * @param email
	 */
	public void setEmail(String email) {
		this.email = email;
	}

	/**
	 * 
	 * @return
	 */
	@Email(message = "No es una dirección de email válida")
	public String getConfEmail() {
		return confEmail;
	}

	/**
	 * 
	 * @param confEmail
	 */
	public void setConfEmail(String confEmail) {
		this.confEmail = confEmail;
	}

	/**
	 * 
	 * @return
	 */
	public List<ProvinciaDic> getListaProvincias() {
		if (listaProvincias == null) {
			listaProvincias = provinciaService.getList();
		}
		return listaProvincias;
	}

	/**
	 * 
	 * @param listaProvincias
	 */
	public void setListaProvincias(List<ProvinciaDic> listaProvincias) {
		this.listaProvincias = listaProvincias;
	}

	/**
	 * 
	 * @return
	 */
	public List<MunicipioDic> getListaMunicipios() {
		if (modo == 1 || modo == 2) {
			if (user.getProvincia() != null) {
				listaMunicipios = municipioService.getList(user.getProvincia());
			}
		} else {
			if (newUser.getProvincia() != null) {
				listaMunicipios = municipioService.getList(newUser
						.getProvincia());
			}
		}
		return listaMunicipios;
	}

	/**
	 * 
	 * @param listaMunicipios
	 */
	public void setListaMunicipios(List<MunicipioDic> listaMunicipios) {
		this.listaMunicipios = listaMunicipios;
	}

	/**
	 * 
	 * @return
	 */
	public List<PerfilDic> getListaPerfiles() {
		return listaPerfiles;
	}

	/**
	 * 
	 * @param listaPerfiles
	 */
	public void setListaPerfiles(List<PerfilDic> listaPerfiles) {
		this.listaPerfiles = listaPerfiles;
	}

	/**
	 * 
	 * @return
	 */
	public String getContraseña() {
		return contraseña;
	}

	/**
	 * 
	 * @param contraseña
	 */
	public void setContraseña(String contraseña) {
		this.contraseña = contraseña;
	}

	/**
	 * 
	 * @return
	 */
	public boolean isGuardado() {
		return guardado;
	}

	/**
	 * 
	 * @param guardado
	 */
	public void setGuardado(boolean guardado) {
		this.guardado = guardado;
	}

}
